%module VSpice
%{
#include "Analysis.h"
#include "Element.h"
#include "VSpice.h"
#include "ReadData.h"
#include "yuv420sp2rgb.h"
#include "Wire.h"

#include "log.h"
%}

%ignore Element::operator=;
%include "Analysis.h"
%include "Element.h"
%include "Wire.h"


int test();

%typemap(jni) unsigned char * "jbyteArray"
%typemap(jtype) unsigned char * "byte[]"
%typemap(jstype) unsigned char * "byte[]"
%typemap(in) unsigned char *img {
    $1 = (unsigned char *)JCALL2(GetByteArrayElements, jenv, $input, 0);
}
%typemap(argout) unsigned char *img {
    JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, 0);
}
%typemap(out) unsigned char * {
    if($1 == NULL) return NULL;

    LOG("NewByteArray");

    int size = arg2 * arg3 * 3;
    $result = JCALL1(NewByteArray, jenv, size);
    JCALL4(SetByteArrayRegion, jenv, $result, 0, size, (jbyte *)$1);
}
%typemap(javain) unsigned char *img "$javainput"
%typemap(javaout) unsigned char * {
    return $jnicall;
}
%typemap(freearg) unsigned char * ""
unsigned char *convert(unsigned char *img, int width, int height);

%typemap(jni) unsigned char * "jbyteArray"
%typemap(jtype) unsigned char * "byte[]"
%typemap(jstype) unsigned char * "byte[]"

%typemap(jni) Element * "jobjectArray"
%typemap(jtype) Element * "Element[]"
%typemap(jstype) Element * "Element[]"

%typemap(jni) int * "jobject"
%typemap(jtype) int * "Integer"
%typemap(jstype) int * "Integer"
%typemap(in) unsigned char *rgb {
    $1 = (unsigned char *)JCALL2(GetByteArrayElements, jenv, $input, 0);
}
%typemap(in) int *size (int temp){
    $1 = (int *)&temp;
}

%typemap(out) Element * {
    if($1 == NULL) return NULL;

    LOG("NewElementArray");

    int size = *arg4;
    $result = JCALL3(NewObjectArray, jenv, size, 
    JCALL1(FindClass, jenv, "com/android/vspice/swig/Element"), 0);

    for(int i = 0 ; i < size ; i++) {
        JCALL3(SetObjectArrayElement, jenv, $result, (jsize)&i, 
            (jobject)&($1[i]));
    }
}
%typemap(javain) unsigned char *rgb "$javainput"
%typemap(javain) int *size "$javainput"
%typemap(javaout) Element * {
    return $jnicall;
}
%typemap(freearg) unsigned char * ""
%typemap(freearg) int * ""
Element *testcv(unsigned char *rgb, int width, int height, int *size);

int GetNumData();

%typemap(jni) (double **data) "jdoubleArray"
%typemap(jtype) double **data "double[]"
%typemap(jstype) double **data "double[]"
%typemap(in) double **data (double *temp){
    $1 = &temp;
}
%typemap(argout) double **data {
    int n = GetNumData();
    JCALL4(SetDoubleArrayRegion, jenv, $input, 0, n, (jdouble *)*$1);
}
%typemap(javain) double **data "$javainput"
%typemap(freearg) double **data ""
bool GetRealData(char *name, double **data);

%typemap(jni) int * "jobject"
%typemap(jtype) int * "Integer"
%typemap(jstype) int * "Integer"

%typemap(in) int *size (int temp){
    $1 = (int *)&temp;
}
%typemap(jni) (char **) "jobjectArray"
%typemap(jtype) char ** "String[]"
%typemap(jstype) char ** "String[]"
%typemap(out) char ** {
    int size = *arg1;
    $result = JCALL3(NewObjectArray, jenv, size, 
    JCALL1(FindClass, jenv, "java/lang/String"), 
    JCALL1(NewStringUTF, jenv, ""));

    for(int i = 0 ; i < size ; i++) {
        JCALL3(SetObjectArrayElement, jenv, $result, (jsize)&i, 
            JCALL1(NewStringUTF, jenv, $1[i]));
    }
    LOG("GetVarName-SetObjectArrayElement");
}
%typemap(javain) int *size "$javainput"
%typemap(javaout) char ** {
    return $jnicall;
}
char **GetVarName(int *size);
